
import java.io.*;
import goldengine.java.*;

/*
 * Licensed Material - Property of Matthew Hawkins (hawkini@4email.net) 
 */
 
public class MyParser implements GPMessageConstants
{
 
    private interface SymbolConstants 
    {
       final int SYMBOL_EOF                     = 0 ;  // (EOF)
       final int SYMBOL_ERROR                   = 1 ;  // (Error)
       final int SYMBOL_WHITESPACE              = 2 ;  // (Whitespace)
       final int SYMBOL_CLOSEBRAC               = 3 ;  // CloseBrac
       final int SYMBOL_DOLLER                  = 4 ;  // Doller
       final int SYMBOL_EQUALTO                 = 5 ;  // EqualTo
       final int SYMBOL_GREATERTHAN             = 6 ;  // GreaterThan
       final int SYMBOL_IDENTIFIER              = 7 ;  // Identifier
       final int SYMBOL_LESSTHAN                = 8 ;  // LessThan
       final int SYMBOL_OPENBRAC                = 9 ;  // OpenBrac
       final int SYMBOL_OPTIONALOPERATOR        = 10;  // OptionalOperator
       final int SYMBOL_OROPERATOR              = 11;  // OrOperator
       final int SYMBOL_PUBLICOPERATOR          = 12;  // PublicOperator
       final int SYMBOL_SEMICOLON               = 13;  // SemiColon
       final int SYMBOL_STRINGLITERAL           = 14;  // StringLiteral
       final int SYMBOL_CAPTURENAME             = 15;  // <CaptureName>
       final int SYMBOL_PATTERN                 = 16;  // <Pattern>
       final int SYMBOL_PATTERNNAME             = 17;  // <PatternName>
       final int SYMBOL_PATTERNREFERENCE        = 18;  // <PatternReference>
       final int SYMBOL_PRIVATESTATEMENT        = 19;  // <PrivateStatement>
       final int SYMBOL_PROGRAM                 = 20;  // <Program>
       final int SYMBOL_PUBLICSTATEMENT         = 21;  // <PublicStatement>
       final int SYMBOL_REGEXSTRING             = 22;  // <RegexString>
       final int SYMBOL_SIMPLEASSIGNMENT        = 23;  // <SimpleAssignment>
       final int SYMBOL_SIMPLEASSIGNMENTPATTERN = 24;  // <SimpleAssignmentPattern>
       final int SYMBOL_STATEMENT               = 25;  // <Statement>
       final int SYMBOL_STATEMENTS              = 26;  // <Statements>
       final int SYMBOL_WORD                    = 27;  // <Word>
    };

    private interface RuleConstants
    {
       final int RULE_PROGRAM                                                 = 0 ;  // <Program> ::= <Statements>
       final int RULE_STATEMENTS                                              = 1 ;  // <Statements> ::= 
       final int RULE_STATEMENTS_SEMICOLON                                    = 2 ;  // <Statements> ::= <Statement> SemiColon <Statements>
       final int RULE_STATEMENT                                               = 3 ;  // <Statement> ::= <PrivateStatement>
       final int RULE_STATEMENT2                                              = 4 ;  // <Statement> ::= <PublicStatement>
       final int RULE_PRIVATESTATEMENT_EQUALTO                                = 5 ;  // <PrivateStatement> ::= <PatternName> EqualTo <Pattern>
       final int RULE_PRIVATESTATEMENT                                        = 6 ;  // <PrivateStatement> ::= <SimpleAssignment>
       final int RULE_PUBLICSTATEMENT_PUBLICOPERATOR_EQUALTO                  = 7 ;  // <PublicStatement> ::= PublicOperator <PatternName> EqualTo <Pattern>
       final int RULE_PUBLICSTATEMENT_PUBLICOPERATOR                          = 8 ;  // <PublicStatement> ::= PublicOperator <SimpleAssignment>
       final int RULE_SIMPLEASSIGNMENT_EQUALTO                                = 9 ;  // <SimpleAssignment> ::= <PatternName> EqualTo <SimpleAssignmentPattern>
       final int RULE_SIMPLEASSIGNMENTPATTERN_STRINGLITERAL                   = 10;  // <SimpleAssignmentPattern> ::= StringLiteral
       final int RULE_PATTERNNAME_IDENTIFIER                                  = 11;  // <PatternName> ::= Identifier
       final int RULE_PATTERN                                                 = 12;  // <Pattern> ::= <Word>
       final int RULE_PATTERN2                                                = 13;  // <Pattern> ::= <RegexString>
       final int RULE_PATTERN3                                                = 14;  // <Pattern> ::= <PatternReference>
       final int RULE_PATTERN4                                                = 15;  // <Pattern> ::= <Pattern> <Pattern>
       final int RULE_PATTERN_OPENBRAC_CLOSEBRAC                              = 16;  // <Pattern> ::= OpenBrac <Pattern> CloseBrac
       final int RULE_PATTERN_OROPERATOR                                      = 17;  // <Pattern> ::= <Pattern> OrOperator <Pattern>
       final int RULE_PATTERN_OPTIONALOPERATOR                                = 18;  // <Pattern> ::= <Pattern> OptionalOperator
       final int RULE_WORD_IDENTIFIER                                         = 19;  // <Word> ::= Identifier
       final int RULE_REGEXSTRING_STRINGLITERAL_LESSTHAN_GREATERTHAN          = 20;  // <RegexString> ::= StringLiteral LessThan <CaptureName> GreaterThan
       final int RULE_PATTERNREFERENCE_DOLLER_IDENTIFIER_LESSTHAN_GREATERTHAN = 21;  // <PatternReference> ::= Doller Identifier LessThan <CaptureName> GreaterThan
       final int RULE_CAPTURENAME_IDENTIFIER                                  = 22;  // <CaptureName> ::= Identifier
    };

   private static BufferedReader buffR;

    /***************************************************************
     * This class will run the engine, and needs a file called config.dat
     * in the current directory. This file should contain two lines,
     * The first should be the absolute path name to the .cgt file, the second
     * should be the source file you wish to parse.
     * @param args Array of arguments.
     ***************************************************************/
    public static void main(String[] args)
    {
       String textToParse = "", compiledGrammar = "";

       try
       {
           buffR = new BufferedReader(new FileReader(new File("./config.dat")));
           compiledGrammar = buffR.readLine();
           textToParse = buffR.readLine();

           buffR.close();
       }
       catch(FileNotFoundException fnfex)
       {
           System.out.println("Config File was not found.\n\n" +
                              "Please place it in the current directory.");
           System.exit(1);
       }
       catch(IOException ioex)
       {
          System.out.println("An error occured while reading config.dat.\n\n" +
                             "Please re-try ensuring the file can be read.");
          System.exit(1);
       }

       GOLDParser parser = new GOLDParser();

       try
       {
          parser.loadCompiledGrammar(compiledGrammar);
          parser.openFile(textToParse);
       }
       catch(ParserException parse)
       {
          System.out.println("**PARSER ERROR**\n" + parse.toString());
          System.exit(1);
       }

       boolean done = false;
       int response = -1;

       while(!done)
       {
          try
            {
                  response = parser.parse();
            }
            catch(ParserException parse)
            {
                System.out.println("**PARSER ERROR**\n" + parse.toString());
                System.exit(1);
            }

            switch(response)
            {
               case gpMsgTokenRead:
                   /* A token was read by the parser. The Token Object can be accessed
                      through the CurrentToken() property:  Parser.CurrentToken */
                   break;

               case gpMsgReduction:
                   /* This message is returned when a rule was reduced by the parse engine.
                      The CurrentReduction property is assigned a Reduction object
                      containing the rule and its related tokens. You can reassign this
                      property to your own customized class. If this is not the case,
                      this message can be ignored and the Reduction object will be used
                      to store the parse tree.  */

                      switch(parser.currentReduction().getParentRule().getTableIndex())
                      {
                         case RuleConstants.RULE_PROGRAM:
                            //<Program> ::= <Statements>
                            break;
                         case RuleConstants.RULE_STATEMENTS:
                            //<Statements> ::= 
                            break;
                         case RuleConstants.RULE_STATEMENTS_SEMICOLON:
                            //<Statements> ::= <Statement> SemiColon <Statements>
                            break;
                         case RuleConstants.RULE_STATEMENT:
                            //<Statement> ::= <PrivateStatement>
                            break;
                         case RuleConstants.RULE_STATEMENT2:
                            //<Statement> ::= <PublicStatement>
                            break;
                         case RuleConstants.RULE_PRIVATESTATEMENT_EQUALTO:
                            //<PrivateStatement> ::= <PatternName> EqualTo <Pattern>
                            break;
                         case RuleConstants.RULE_PRIVATESTATEMENT:
                            //<PrivateStatement> ::= <SimpleAssignment>
                            break;
                         case RuleConstants.RULE_PUBLICSTATEMENT_PUBLICOPERATOR_EQUALTO:
                            //<PublicStatement> ::= PublicOperator <PatternName> EqualTo <Pattern>
                            break;
                         case RuleConstants.RULE_PUBLICSTATEMENT_PUBLICOPERATOR:
                            //<PublicStatement> ::= PublicOperator <SimpleAssignment>
                            break;
                         case RuleConstants.RULE_SIMPLEASSIGNMENT_EQUALTO:
                            //<SimpleAssignment> ::= <PatternName> EqualTo <SimpleAssignmentPattern>
                            break;
                         case RuleConstants.RULE_SIMPLEASSIGNMENTPATTERN_STRINGLITERAL:
                            //<SimpleAssignmentPattern> ::= StringLiteral
                            break;
                         case RuleConstants.RULE_PATTERNNAME_IDENTIFIER:
                            //<PatternName> ::= Identifier
                            break;
                         case RuleConstants.RULE_PATTERN:
                            //<Pattern> ::= <Word>
                            break;
                         case RuleConstants.RULE_PATTERN2:
                            //<Pattern> ::= <RegexString>
                            break;
                         case RuleConstants.RULE_PATTERN3:
                            //<Pattern> ::= <PatternReference>
                            break;
                         case RuleConstants.RULE_PATTERN4:
                            //<Pattern> ::= <Pattern> <Pattern>
                            break;
                         case RuleConstants.RULE_PATTERN_OPENBRAC_CLOSEBRAC:
                            //<Pattern> ::= OpenBrac <Pattern> CloseBrac
                            break;
                         case RuleConstants.RULE_PATTERN_OROPERATOR:
                            //<Pattern> ::= <Pattern> OrOperator <Pattern>
                            break;
                         case RuleConstants.RULE_PATTERN_OPTIONALOPERATOR:
                            //<Pattern> ::= <Pattern> OptionalOperator
                            break;
                         case RuleConstants.RULE_WORD_IDENTIFIER:
                            //<Word> ::= Identifier
                            break;
                         case RuleConstants.RULE_REGEXSTRING_STRINGLITERAL_LESSTHAN_GREATERTHAN:
                            //<RegexString> ::= StringLiteral LessThan <CaptureName> GreaterThan
                            break;
                         case RuleConstants.RULE_PATTERNREFERENCE_DOLLER_IDENTIFIER_LESSTHAN_GREATERTHAN:
                            //<PatternReference> ::= Doller Identifier LessThan <CaptureName> GreaterThan
                            break;
                         case RuleConstants.RULE_CAPTURENAME_IDENTIFIER:
                            //<CaptureName> ::= Identifier
                            break;
                      }

                          //Parser.Reduction = //Object you created to store the rule

                    // ************************************** log file
                    System.out.println("gpMsgReduction");
                    Reduction myRed = parser.currentReduction();
                    System.out.println(myRed.getParentRule().getText());
                    // ************************************** end log

                    break;

                case gpMsgAccept:
                    /* The program was accepted by the parsing engine */

                    // ************************************** log file
                    System.out.println("gpMsgAccept");
                    // ************************************** end log

                    done = true;

                    break;

                case gpMsgLexicalError:
                    /* Place code here to handle a illegal or unrecognized token
                           To recover, pop the token from the stack: Parser.PopInputToken */

                    // ************************************** log file
                    System.out.println("gpMsgLexicalError");
                    // ************************************** end log

                    parser.popInputToken();

                    break;

                case gpMsgNotLoadedError:
                    /* Load the Compiled Grammar Table file first. */

                    // ************************************** log file
                    System.out.println("gpMsgNotLoadedError");
                    // ************************************** end log

                    done = true;

                    break;

                case gpMsgSyntaxError:
                    /* This is a syntax error: the source has produced a token that was
                           not expected by the LALR State Machine. The expected tokens are stored
                           into the Tokens() list. To recover, push one of the
                              expected tokens onto the parser's input queue (the first in this case):
                           You should limit the number of times this type of recovery can take
                           place. */

                    done = true;

                    Token theTok = parser.currentToken();
                    System.out.println("Token not expected: " + (String)theTok.getData());

                    // ************************************** log file
                    System.out.println("gpMsgSyntaxError");
                    // ************************************** end log

                    break;

                case gpMsgCommentError:
                    /* The end of the input was reached while reading a comment.
                             This is caused by a comment that was not terminated */

                    // ************************************** log file
                    System.out.println("gpMsgCommentError");
                    // ************************************** end log

                    done = true;

                              break;

                case gpMsgInternalError:
                    /* Something horrid happened inside the parser. You cannot recover */

                    // ************************************** log file
                    System.out.println("gpMsgInternalError");
                    // ************************************** end log

                    done = true;

                    break;
            }
        }
        try
        {
              parser.closeFile();
        }
        catch(ParserException parse)
        {
            System.out.println("**PARSER ERROR**\n" + parse.toString());
            System.exit(1);
        }
    }
}
